package demo.android.com.mvpdemo.mvp3.base;

import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;

/**
 * Created by Vya on 2018/1/4 0004.
 */

public class BasePresenter <V extends BaseView,M extends BaseModel>{
    private SoftReference<V> mReference;  //SoftReference在OOM时会回收

    private V mProxyView;
    private M mModel;

    public void attach(V view){
        //意思是在OOM发生之前,它才会被GC掉,而没有发生OOM之前的GC,是不会将SoftReference的对象GC掉的!
        mReference = new SoftReference<V>(view);
        mProxyView = (V) Proxy.newProxyInstance(view.getClass().getClassLoader(), view.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                if(mReference == null || mReference.get() == null){
                    return null;
                }
                return method.invoke(mReference.get(),objects);
            }
        });

        //使用反射的方式拿到BasePresenter上的注解M并创建实例
        Type[] params = ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments();
        try {
            // 最好要判断一下类型
            mModel = (M) ((Class)params[1]).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    public void detach()
    {
        this.mReference.clear();
        this.mReference = null;
        //this.mProxyView = null;
    }

    public M getModel() {
        return mModel;
    }

    public V getView() {
        return mProxyView;
    }
}
